package web.operator;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import web.clazz.Clazz;

/**用于扫描所有编译后的类文件，保存到{@link #classSet}中。
 * <p>
 * {@link TypeOperator}
 * {@link EntityOperator}
 * </p>
 * @author 乐渊
 * @version 1.0
 *
 * */
public class ClassScanner {
	
	private List<Map<String, File>> listFile = new ArrayList<>();
	
	/**扫描包
	 * @param packageNames 包名数组
	 * */
	public Set<Clazz> getClassesByPackgename(List<String> packageNames) {
		listFile.clear();
		List<Map<String,File>> fileList = new ArrayList<>();
		
		packageNames.forEach(packagename ->{
			String path = packagename.replace('.','/');
			URL url = getClass().getClassLoader().getResource(path);
			Map<String,File> map = new HashMap<>();
			map.put(packagename+".", new File(url.getFile()));
			fileList.add(map);
		});
		
		fileList.forEach(item -> classScan(item));
		Set<Clazz> classSet = getclassSet();
		return classSet;
	}
	
	/**扫描类 保存到listFile中
	 * @param map key:记录当前包名 value：记录当前文件
	 * */
	private void classScan(Map<String,File> map) {
		for(String key:map.keySet()){
			
			File file = map.get(key);
			
			file.listFiles(item -> {
				if(item.isDirectory()){
					Map<String,File> m = new HashMap<>();
					String path = item.getName();
					m.put(key+path+".", item);
					classScan(m);
				}else if(item.getName().endsWith(".class")){
					Map<String,File> m = new HashMap<>();
					m.put(key, item);
					listFile.add(m);
				}
				return false;
			});
		}
	}
	
	/**反射所有类的实例
	 * @return classSet
	 * */
	private Set<Clazz> getclassSet() {
		Set<Clazz> classSet = new HashSet<>();
		listFile.forEach(map ->{
			for(String key:map.keySet()){
				Clazz cla = new Clazz();
				String filepath = map.get(key).getName();
				try {
					cla.setClazz(Class.forName(key+filepath.split("\\.")[0]));
					classSet.add(cla);
				} catch (ClassNotFoundException e) {
					e.printStackTrace();
				}
			}
		});
		return classSet;
	}
}
